package com.roads.project.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.context.AnalysisContextImpl;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.converters.ConverterKeyBuild;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.read.metadata.holder.ReadSheetHolder;
import com.roads.common.annotation.Log;
import com.roads.common.core.controller.BaseController;
import com.roads.common.core.domain.AjaxResult;
import com.roads.common.core.page.TableDataInfo;
import com.roads.common.enums.BusinessType;
import com.roads.common.exception.ServiceException;
import com.roads.common.utils.StringUtils;
import com.roads.common.utils.poi.ExcelUtils;
import com.roads.project.domain.ProBoqArrange;
import com.roads.project.domain.template.ProBoqArrangeTemplate;
import com.roads.project.gy.GyBoq;
import com.roads.project.gy.GyHouseBoq;
import com.roads.project.gy.GyHouseType;
import com.roads.project.service.IProBoqArrangeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 清单整理Controller
 *
 * @author nhp
 * @date 2021-11-22
 */
@RestController
@RequestMapping("/project/arrange")
public class ProBoqArrangeController extends BaseController {

    @Autowired
    private IProBoqArrangeService proBoqArrangeService;

    /**
     * 查询清单整理列表
     */
    @PreAuthorize("@ss.hasPermi('project:arrange:list')")
    @GetMapping("/list")
    public TableDataInfo list(ProBoqArrange proBoqArrange) {
        startPage();
        proBoqArrange.setCreateBy(getUsername());
        List<ProBoqArrange> list = proBoqArrangeService.selectProBoqArrangeList(proBoqArrange);
        return getDataTable(list);
    }

    @GetMapping("/importTemplate")
    public AjaxResult importTemplate() {
        ExcelUtils<ProBoqArrangeTemplate> utils = new ExcelUtils<ProBoqArrangeTemplate>(ProBoqArrangeTemplate.class);
        return utils.importTemplateExcel("清单模板");
    }

    @Log(title = "清单整理", businessType = BusinessType.IMPORT)
    @PreAuthorize("@ss.hasPermi('project:arrange:import')")
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file) throws Exception {
        ExcelUtils<ProBoqArrangeTemplate> utils = new ExcelUtils<>(ProBoqArrangeTemplate.class);
        List<ProBoqArrangeTemplate> list = utils.importExcel(file.getInputStream());
        String userName = getUsername();
        String message = proBoqArrangeService.importData(list, userName);
        return AjaxResult.success(message);
    }

    @Log(title = "清单整理-根牙房建", businessType = BusinessType.IMPORT)
    @PreAuthorize("@ss.hasPermi('project:arrange:import')")
    @PostMapping("/importGyHouseData")
    public AjaxResult importGyHouseData(MultipartFile file) {
        try {
            List<GyHouseType> types = new ArrayList<>();
            // 读取第一个Sheet
            EasyExcel.read(file.getInputStream(), GyHouseType.class, new AnalysisEventListener<GyHouseType>() {
                @Override
                public void invoke(GyHouseType gyHouseType, AnalysisContext analysisContext) {
                    types.add(gyHouseType);
                }

                @Override
                public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                }
            }).sheet().doRead();
            // 读取后面的excel
            int sheetNum = 1;
            List<GyBoq> boqs = new ArrayList<>();
            for (GyHouseType type : types) {
                Integer number = Integer.parseInt(type.getCode());
                Integer typeNumber = 800 + number;
                String typeBoqCode = typeNumber.toString();
                GyBoq typeBoq = new GyBoq();
                typeBoq.setCode(typeBoqCode);
                typeBoq.setName(type.getName());
                boqs.add(typeBoq);
                // 读取其他sheet页数据
                EasyExcel.read(file.getInputStream(), GyHouseBoq.class, new AnalysisEventListener<GyHouseBoq>() {
                    Integer boqNumber = 1;
                    boolean lastIsNull = true;
                    String parentCode = typeBoqCode;
                    @Override
                    public void invoke(GyHouseBoq gyHouseBoq, AnalysisContext analysisContext) {
                        String boqCode = "";
                        if (StringUtils.isEmpty(gyHouseBoq.getBoqCode()) && StringUtils.isNotEmpty(gyHouseBoq.getBoqName())) {
                            if (lastIsNull) {
                                boqCode = parentCode + "-" + boqNumber;
                            } else {
                                boqCode = typeBoqCode + "-" + boqNumber;
                            }
                            parentCode = boqCode;
                            lastIsNull = true;
                            boqNumber++;
                        } else {
                            boqCode = parentCode + "-" + gyHouseBoq.getBoqCode();
                            lastIsNull = false;
                        }
                        GyBoq boq = new GyBoq();
                        boq.setCode(boqCode);
                        boq.setName(gyHouseBoq.getBoqName());
                        boq.setUnit(gyHouseBoq.getUnit());
                        boq.setAmount(gyHouseBoq.getAmount());
                        boq.setPrice(gyHouseBoq.getPrice());
                        boq.setTotal(gyHouseBoq.getTotal());
                        boq.setDescribe(gyHouseBoq.getDescribe());
                        boqs.add(boq);
                    }

                    @Override
                    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
                        // 找到sheet页是否存在
                        ReadSheetHolder sheetHolder = (ReadSheetHolder) context.currentReadHolder();
                        String sheetName = sheetHolder.getSheetName();
                        boolean flag = false;
                        for (GyHouseType type : types) {
                            if (type.getName().equalsIgnoreCase(sheetName)) {
                                flag = true;
                                break;
                            }
                        }
                        if (!flag) {
                            throw new ServiceException("sheet名称未找到");
                        }
                    }

                    @Override
                    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

                    }
                }).sheet(sheetNum).doRead();
                sheetNum ++;
            }

            for (GyBoq boq : boqs) {
                System.out.println("清单编号：" + boq.getCode() + ",清单名称：" + boq.getName());
            }
            ExcelUtils<GyBoq> util = new ExcelUtils<>(GyBoq.class);
            return util.exportExcel(boqs, "根牙房建清单数据");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return AjaxResult.success();
    }

    /**
     * 清单整理
     *
     * @return 结果
     */
    @Log(title = "清单整理", businessType = BusinessType.UPDATE)
    @PreAuthorize("@ss.hasPermi('project:arrange:edit')")
    @GetMapping("/arrange")
    public AjaxResult arrange() {
        String userName = getUsername();
        proBoqArrangeService.arrange(userName);
        return success();
    }

    /**
     * 自动补全前的验证
     *
     * @return 结果
     */
    @PreAuthorize("@ss.hasPermi('project:arrange:edit')")
    @GetMapping("/beforeAutoComplementAll")
    public AjaxResult beforeAutoComplementAll() {
        ProBoqArrange search = new ProBoqArrange();
        search.setCreateBy(getUsername());
        search.setStatus(1);
        List<ProBoqArrange> list = proBoqArrangeService.selectProBoqArrangeList(search);
        if (list.size() > 0) {
            return error("请先处理异常清单");
        }
        return success();
    }

    /**
     * 自动补全
     *
     * @return 结果
     */
    @Log(title = "清单整理-自动补全", businessType = BusinessType.UPDATE)
    @PreAuthorize("@ss.hasPermi('project:arrange:edit')")
    @GetMapping("/autoComplementAll")
    public AjaxResult autoComplementAll() {
        String userName = getUsername();
        proBoqArrangeService.autoComplementAll(userName);
        return success();
    }

    /**
     * 忽略警告
     *
     * @return 结果
     */
    @Log(title = "清单整理-忽略警告", businessType = BusinessType.UPDATE)
    @PreAuthorize("@ss.hasPermi('project:arrange:edit')")
    @GetMapping("/ignoreWarnings")
    public AjaxResult ignoreWarnings() {
        String userName = getUsername();
        proBoqArrangeService.ignoreWarnings(userName);
        return success();
    }

    /**
     * 忽略
     *
     * @return 结果
     */
    @GetMapping("/ignore/{id}")
    public AjaxResult ignore(@PathVariable long id) {
        proBoqArrangeService.ignore(id);
        return success();
    }

    /**
     * 自动补全
     *
     * @return 结果
     */
    @GetMapping("/beforeComplement/{id}")
    public AjaxResult beforeComplement(@PathVariable long id) {
        ProBoqArrange arrange = proBoqArrangeService.getLatelyById(id);
        if (arrange == null) {
            return error("未找到可以补全的清单");
        }
        return AjaxResult.success(arrange);
    }

    @PostMapping("/autoComplement")
    public AjaxResult autoComplement(Long id, Long bId) {
        proBoqArrangeService.autoComplement(id, bId, getUsername());
        return success();
    }

    /**
     * 清单整理
     *
     * @return
     */
    @Log(title = "清单整理", businessType = BusinessType.CLEAN)
    @PreAuthorize("@ss.hasPermi('project:arrange:remove')")
    @GetMapping("/clean")
    public AjaxResult clean() {
        String userName = getUsername();
        proBoqArrangeService.clean(userName);
        return success();
    }

    @GetMapping("/exportCheck")
    public AjaxResult exportCheck() {
        String userName = getUsername();
        int count = proBoqArrangeService.countErrorData(userName);
        if (count > 0) {
            return error("请先处理异常和警告数据");
        }
        return success();
    }

    /**
     * 导出清单整理列表
     */
    @PreAuthorize("@ss.hasPermi('project:arrange:export')")
    @Log(title = "清单整理", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(ProBoqArrange proBoqArrange) {
        List<ProBoqArrange> list = proBoqArrangeService.selectProBoqArrangeList(proBoqArrange);
        ExcelUtils<ProBoqArrange> util = new ExcelUtils<>(ProBoqArrange.class);
        return util.exportExcel(list, "清单数据");
    }

}
